<!DOCTYPE html>
<!--自定义配置-->
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <p>
      <textarea name="" id="options" rows="10" style="width: 100%"></textarea>
    </p>
    <p>
      <textarea
        name=""
        id="optionsobj"
        rows="10"
        style="width: 100%"
      ></textarea>
    </p>
    <button onclick="loadOptions()">loadOptions</button>
    <button onclick="logOptions()">log options</button>
    <div id="content"></div>
    <script>
      var options = {
        name: {
          label: "姓名",
          type: "String",
          value: "nnn",
          description: "描述",
        },
        age: {
          label: "年龄",
          type: "Number",
          value: 232,
        },
        gender: {
          label: "性别",
          type: "Radio",
          selections: [
            {
              name: "man",
              value: "1",
            },
            {
              name: "woman",
              value: 0,
            },
          ],
          value: 0,
        },
        hobby: {
          label: "爱好",
          type: "Checkbox",
          selections: [
            {
              name: "play ball",
              value: "1",
            },
            {
              name: "reading",
              value: 2,
            },
            {
              name: "eating",
              value: 3,
            },
          ],
          value: [2, 3],
        },
        list: {
          label: "列表",
          type: "Array",
          options: {
            name: {
              label: "姓名",
              type: "String",
              description: "描述",
            },
            age: {
              label: "年龄",
              type: "Number",
            },
            other: {
              label: "其它",
              type: "Object",
              options: {
                name: {
                  label: "姓名",
                  type: "String",
                  description: "描述",
                },
              },
            },
            list: {
              label: "列表",
              type: "Array",
              options: {
                name: {
                  label: "姓名",
                  type: "String",
                  description: "描述",
                },
                age: {
                  label: "年龄",
                  type: "Number",
                },
                other: {
                  label: "其它",
                  type: "Object",
                  options: {
                    name: {
                      label: "姓名",
                      type: "String",
                      description: "描述",
                    },
                  },
                },
              },
              value: [
                {
                  name: "name1",
                  age: 13,
                  other: {
                    name: "othername1",
                  },
                },
                {
                  name: "name2",
                  age: 10,
                  other: {
                    name: "othername2",
                  },
                },
              ],
            },
          },
          value: [
            {
              name: "name1",
              age: 13,
              other: {
                name: "othername1",
              },
              list: [
                {
                  name: "name1",
                  age: 13,
                  other: {
                    name: "othername1",
                  },
                },
                {
                  name: "name2",
                  age: 10,
                  other: {
                    name: "othername2",
                  },
                },
              ],
            },
            {
              name: "name2",
              age: 10,
              other: {
                name: "othername2",
              },
              list: [
                {
                  name: "name1",
                  age: 13,
                  other: {
                    name: "othername1",
                  },
                },
                {
                  name: "name2",
                  age: 10,
                  other: {
                    name: "othername2",
                  },
                },
              ],
            },
          ],
        },
        other: {
          label: "其它",
          type: "Object",
          options: {
            name: {
              label: "姓名",
              type: "Text",
              value: "nnn",
            },
            age: {
              label: "年龄",
              type: "Number",
              value: 232,
              description: "描述",
            },
            gender: {
              label: "性别",
              type: "Radio",
              selections: [
                {
                  name: "man",
                  value: "1",
                },
                {
                  name: "woman",
                  value: 0,
                },
              ],
              value: 0,
            },
            hobby: {
              label: "爱好",
              type: "Checkbox",
              selections: [
                {
                  name: "play ball",
                  value: "1",
                },
                {
                  name: "reading",
                  value: 2,
                },
                {
                  name: "eating",
                  value: 3,
                },
              ],
            },
          },
        },
      };

      function rendOptions(options, path) {
        path = path || "";
        var box = document.createElement("div");
        box.style.marginLeft = "20px";
        for (var key in options) {
          var option = options[key];
          switch (option.type) {
            case "Object": {
              box.appendChild(createObjectOption(option, path + "." + key));
              break;
            }
            case "Array": {
              box.appendChild(createArrayOption(option, path + "." + key));
              break;
            }
            case "String": {
              box.appendChild(createStringOption(option));
              break;
            }
            case "Text": {
              box.appendChild(createTextOption(option));
              break;
            }
            case "Number": {
              box.appendChild(createNumberOption(option));
              break;
            }
            case "Radio": {
              box.appendChild(createRadioOption(key, option, path));
              break;
            }
            case "Checkbox": {
              box.appendChild(createCheckboxOption(key, option, path));
              break;
            }
            default: {
            }
          }
          box.appendChild(document.createElement("hr"));
        }
        return box;
      }

      function createStringOption(option) {
        var box = document.createElement("div");
        var label = document.createElement("h4");
        label.innerText = option.label;
        var input = document.createElement("input");
        input.type = "text";
        input.value = option.value;

        input.addEventListener("keyup", function () {
          option.value = input.value;
        });

        var description = document.createElement("p");
        description.innerText = option.description || "";
        box.appendChild(label);
        box.appendChild(input);
        box.appendChild(description);
        return box;
      }

      function createTextOption(option) {
        var box = document.createElement("div");
        var label = document.createElement("h4");
        label.innerText = option.label;
        var input = document.createElement("textarea");
        input.value = option.value;

        input.addEventListener("keyup", function () {
          option.value = input.value;
        });

        var description = document.createElement("p");
        description.innerText = option.description || "";
        box.appendChild(label);
        box.appendChild(input);
        box.appendChild(description);
        return box;
      }

      function createNumberOption(option) {
        var box = document.createElement("div");
        var label = document.createElement("h4");
        label.innerText = option.label;
        var input = document.createElement("input");
        input.type = "number";
        input.value = option.value;

        input.addEventListener("keyup", function () {
          option.value = input.value;
        });

        var description = document.createElement("p");
        description.innerText = option.description || "";
        box.appendChild(label);
        box.appendChild(input);
        box.appendChild(description);
        return box;
      }

      function createObjectOption(option, path) {
        var box = document.createElement("div");
        var label = document.createElement("h4");
        label.innerText = option.label;
        var objextBox = rendOptions(option.options, path);

        var description = document.createElement("p");
        description.innerText = option.description || "";
        box.appendChild(label);
        box.appendChild(objextBox);
        box.appendChild(description);
        return box;
      }

      function mixOption(options, value) {
        var newOptions = JSON.parse(JSON.stringify(options));
        for (var key in newOptions) {
          var option = newOptions[key];
          switch (option.type) {
            case "Object": {
              option.options = mixOption(option.options, value[key]);
              break;
            }
            default: {
              option.value = value[key];
            }
          }
        }
        return newOptions;
      }

      function createArrayOption(option, path) {
        var box = document.createElement("div");
        var boxArr = document.createElement("div");
        var label = document.createElement("h4");
        label.innerText = option.label;
        box.appendChild(label);
        box.appendChild(boxArr);

        option.optionsArr = [];
        debugger;
        option.value = option.value || [];
        option.value.forEach((val) => {
          var newOptions = mixOption(option.options, val);
          option.optionsArr.push(newOptions);
          var boxItem = rendOptions(newOptions, path);
          boxArr.appendChild(boxItem);
        });

        var description = document.createElement("p");
        description.innerText = option.description || "";
        box.appendChild(description);
        return box;
      }

      function createRadioOption(key, option, path) {
        var box = document.createElement("div");
        var label = document.createElement("h4");
        label.innerText = option.label;
        box.appendChild(label);
        var oncheck = function () {
          option.value = this.value;
        };

        option.selections.forEach((selection) => {
          var label = document.createElement("label");
          var input = document.createElement("input");
          var textNode = document.createElement("span");
          textNode.innerText = selection.name;
          label.appendChild(input);
          label.appendChild(textNode);
          input.type = "radio";
          input.name = path + "." + key;
          input.value = selection.value;

          if (selection.value == option.value) {
            input.checked = true;
          }
          input.addEventListener("click", oncheck);
          box.appendChild(label);
        });

        var description = document.createElement("p");
        description.innerText = option.description || "";

        box.appendChild(description);
        return box;
      }

      function createCheckboxOption(key, option, path) {
        var box = document.createElement("div");
        var label = document.createElement("h4");
        label.innerText = option.label;
        box.appendChild(label);
        option.value = option.value || [];
        var oncheck = function () {
          var valIndex = option.value.indexOf(this.value);
          if (valIndex == -1) {
            option.value.push(this.value);
          } else {
            option.value.splice(valIndex, 1);
          }
        };

        option.selections.forEach((selection) => {
          var label = document.createElement("label");
          var input = document.createElement("input");
          var textNode = document.createElement("span");
          textNode.innerText = selection.name;
          label.appendChild(input);
          label.appendChild(textNode);
          input.type = "checkbox";
          input.name = path + "." + key;
          input.value = selection.value;

          if (option.value && option.value.indexOf(selection.value) > -1) {
            input.checked = true;
          }
          input.addEventListener("click", oncheck);
          box.appendChild(label);
        });

        var description = document.createElement("p");
        description.innerText = option.description || "";

        box.appendChild(description);
        return box;
      }

      function getOptions(optionsMetadata) {
        var options = {};
        for (var key in optionsMetadata) {
          var option = optionsMetadata[key];
          if (option.type == "Object") {
            options[key] = getOptions(option.options);
          } else if (option.type == "Array") {
            var value = [];
            option.optionsArr.forEach((ops) => {
              value.push(getOptions(ops));
            });
            option.value = value;
            options[key] = value;
          } else {
            options[key] = option.value;
          }
        }
        return options;
      }

      document.getElementById("options").value = JSON.stringify(options);

      function loadOptions() {
        options = JSON.parse(document.getElementById("options").value);
        var container = document.getElementById("content");
        container.innerHTML = "";
        container.appendChild(rendOptions(options));
      }

      function logOptions() {
        console.log(options);

        document.getElementById("optionsobj").value = JSON.stringify(
          getOptions(options)
        );

        document.getElementById("options").value = JSON.stringify(options);
      }
    </script>
  </body>
</html>
